Slide Deck


Exercises

Initialize a repository

In this exercise, we will:

  • use git init to initalize a git repo in your project’s root directory
  • view contents of the project folder before and after git initialization

Open a terminal emulator and use cd to navigate to the root directory of the project that you would like to turn into a git repository.

You can use the chunk of code below, where <path/to/your/project> should be replaced with an appropriate absolute or relative file path to the root directory of your project.

cd <path/to/your/project>

Once you have navigated to the correct directory, use the ls command to list files in the directory. Take note of what files are included. Then use the ls -a command to list all files in the directory.

Now initialize a git repository using the following command.

git init

Again, use the ls and ls -a commands to list files in the directory. What has changed?

The output of ls should be the same as before. However, when you use ls -a you should now see a new directory called .git.

The .git directory is where all relevant information for version control is stored. There are several files and subdirectories included in this directory. In general, you should not need to worry about what is happening in this directory. However, you should note that:

  • the only thing that makes something a git repository is the presence of this .git directory
  • deleting this directory will remove the project from version control
  • if your project is also stored in a Sharepoint/Dropbox folder, you need to make sure that the contents of this directory stays synchronized across computers that work with. Strange behavior can result from incompletely synchronized .git folders.

If you would like to read more about what is inclued in the .git folder, you can check out the resources below:


First commit

In this exercise, we will:

  • use the git add to stage files for commit
  • use git commit to make a commit

Before you start, make sure that your terminal emulator is still in the correct directory by using pwd. If you are not in the correct folder, use cd to navigate to the root directory of your folder.

Once you are in the correct directory, execute the following command:

git status

The output will look something like this:

[TODO]

Note that git is telling you that there are files in this directory that are not being tracked.

To make a new commit, we generally use the command

git add <file_name1> <file_name2> <...>

Use this command to stage all of the R scripts in the project for commit.

  • [TODO]
  • [TODO]

DO NOT stage any of the following files (yet).

  • [TODO]
  • [TODO]

Exercise: What is an efficient way to use pattern matching to add all R scripts with minimal effort?

We could use the following command:

git add *.R

If this command is executed from the projects root directory, then it will add all files with the .R extension included in your project.

Or if all your R scripts are contained in a directory, e.g., named code, you could add the folder.

git add code

Pattern matches can be useful for adding multiple files, but keep two things in mind:

First, you may consider avoiding commits with multiple files implementing multiple things at the same time. It may be better to split up the files across different commits.

Second, the behavior of * is somewhat unexpected in this circumstance:

git add *

This will add all files in your project except any dot-files (i.e., files whose name begins with .). This may miss some important files.

To add all files correctly use:

git add --all

Once you have confirmed that you have staged the appropriate files for commit, make the commit using the following command:

git commit -m "<add-your-message-here>"

Add an informative message!

Take a final look at git status. What has changed?

Run the following command to view the project history:

git log --oneline


Second commit

In this exercise, we will:

  • make a modification to a file
  • use git diff to see what modifications have been made to a file
  • commit a new version of the file
  • use git log to look at the history of a project

Open [TODO] script in the R studio editor. Modify line [TODO] to read as follows:

[TODO]

Save the file in R Studio. Confirm that the file has saved by ensuring that the name of the file has changed from red to black. (You would be surprised how much confusion can be caused by forgetting to save files)

Take a look at git status. What does it have to say about the modified file?

Use the following command to view the difference between the new version of the file and the version on the current commit.

git diff [TODO]

If all of the changes fit on one screen, the differences will simply print to the console.

If there are A LOT of changes, then you can scroll through the differences either using: enter, page up/down, or arrow keys. When you are done browsing the changes, press q to return to the command line.

Next, stage the file for commit:

git add [TODO]

Exercise: We are now going to do something a little bit scary. We are going to run the git commit command but forget to include a message 😱

git commit

More than likely you will see the following on the screen:

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.

But if you try to type nothing happens. What the…

The exercise is simple: escape!

What happened here? When you forget to include a commit message, git launches a text editor program on your computer. The default text editor that git uses is vim, a powerful, but painfully minimal and more painfully complex editor.

The key part of this solution is: DON’T PANIC. We will get through this together.

Follow these precise steps:

  • type i
    • you should see -- INSERT -- at the bottom of the screen
    • now when you type you will actually see letters appear!
  • use the keyboard as normal to type your commit message
    • notice that you cannot use the mouse to select the cursors position, you have to use the arrow keys
  • when you have finished your message press esc
    • you should no longer see -- INSERT -- at the bottom
  • type :x (colon and the x key)
    • you will see :x appear at the bottom of the screen
  • press enter to save the commit message and quit vim

This will complete the commit. But what the heck just happened?!

In vim, we use i to enter INSERT mode, which is where we actually get to type things.

Pressing esc exited from INSERT mode (back to what is called NORMAL mode).

The colon key takes us into command-line mode. This is where we can execute a host of commands (e.g., find and replace text, save a document, etc…). Think of this like a text-based tool bar for vim.

In command-line mode, we execute the command x which is to save and close the document.

This is exactly what git was asking us to do to complete the commit – save a message.

If all this was too scary for you, you have two options:

Option 1: abandon the commit! Before you do anything else in vim type :q!, which will quit vim without saving. This abandons the commit. Then you can use the one-liner git commit -m "<with-a-message-this-time-dummy>" to complete the commit.

Option 2: configure a different text editor for git! Read more here.


Third commit

In this exercise, we will:

  • add a temporary file to a new commit
  • demonstrate renaming files using git mv in a new commit
  • delete a file using git rm in a new commit

In R Studio, open a new file, add whatever you want to the file, and save it in the [TODO] directory. Name the file foo.R.

Use the following commands to commit this new file:

git add [TODO]/foo.R
git commit -m "Add temporary file to demonstrate renaming and removing"

To rename the file use:

git mv [TODO]/foo.R [TODO]/bar.R

Check git status to see what git thinks about this change! To commit, run:

git commit -m "Rename temporary file"

To remove the file use:

git rm [TODO]/bar.R

Check git status to see what git thinks about this change! To commit, run:

git commit -m "Remove temporary file"

Exercise: Repeat the above process of creating a new file in the [TODO] directory named foo.R. Add it to a new commit using git add and git commit. Now suppose you forget to use git mv to rename the file and instead use plain old mv:

mv [TODO]/foo.R [TODO]/bar.R

Check git status to see what git thinks has happened. What do you need to do to complete the process of committing the renamed file?

Notice that git status should show [TODO/foo.R] as being deleted and show [TODO/bar.R] as an Untracked file.

To complete the commit we need to run:

git add [TODO/bar.R]
git rm [TODO/foo.R]
git commit -m "Rename temporary file"


Exercise: In the previous exercise, you again renamed the file [TODO]/foo.R to [TODO/bar.R]. Now create a commit that removes [TODO/bar.R] but does not delete the file from your local directory.

This can be accomplished using the following (not very intuitively named) option:

git remove --cached [TODO]/bar.R
git commit -m "Remove temporary file"

Using ls should confirm that [TODO]/bar.R has not been deleted from your directory.

Checking git status should show that [TODO]/bar.R is now treated as any other untracked file. For example, it could be added back to a new commit.


Ignoring files

In this exercise, we will:

  • create a .gitignore file to ignore certain files

After completion of the previous exercise, you should have a file named [TODO]/bar.R that is untracked by git. If you did not complete the previous exercise or do not have such a file available, then create one by running:

touch [TODO]/bar.R

Now we are ready to create our .gitignore file. In R Studio, select File: New File: Text file.

Save the file as .gitignore by clicking File: Save as: and type .gitignore.

Now add the following text to the .gitignore file

# don't want credentials in git!
.Renviron
# ignoring this file to see behavior
[TODO]/bar.R

Save the file when you are done adding the text.

Now check git status again. You should no longer see [TODO]/bar.R appear as an untracked file.

Exercise: You may have also noticed that git is now treating the .gitignore file itself as an untracked file. Here’s what should be an easy exercise by now (hopefully!) – make a new commit that includes the .gitignore file

We can execute the following commands:

git add .gitignore
git commit -m "Add .gitignore to repo"


Pushing files to GitHub

In this exercise, we will:

  • create an empty GitHub repository
  • use git remote add to create a link between our local repository and the GitHub repository
  • create ssh credentials to allow us to push to GitHub
  • use git push to push files to GitHub


Practicing add/commit/push

In this exercise, we will:

  • write a README.md file for your GitHub repository
  • add, commit, and push README.md to your GitHub repository


Creating and merging branches

In this exercise, we will:

  • create a new branch
  • make a commit on the new branch
  • merge the new branch with main
  • delete the new branch


Resolving merge conflicts

In this exercise, we will:

  • create a new branch
  • make a commit on the new branch
  • checkout the main branch
  • make a commit on the main branch
  • attempt to merge when conflicts are present
  • resolve conflicts and complete the merge


Pull requests and upstream tracking

In this exercise, we will work in pairs. Designate a partner as User A and User B.

First, User A will:

  • fork an existing repository
  • clone the repository to create a local repository
  • make changes to the local repository
  • push changes to GitHub
  • submit a pull request

Next, User B will:

  • add User A’s repository as a remote
  • fetch User A’s repository
  • merge User A’s changes to their local repository
  • push their changes to GitHub

Then, we will use upstream tracking by User A of User B’s repository. User B will:

  • make changes to their local repository
  • push those changes to GitHub

Finally, User A will:

  • add User B’s repository as an upstream remote
  • fetch User B’s repository
  • merge User B’s changes into their local repository
  • push their changes to GitHub

If you have time, switch roles and repeat the exercise!